package com.ybear.ybnetworkutil.http;

import android.app.Application;

import androidx.annotation.NonNull;

import com.ybear.ybnetworkutil.annotations.ReCountTrigger;
import com.ybear.ybnetworkutil.annotations.TriggerNetworkType;
import com.ybear.ybnetworkutil.call.OnNetworkChangeListener;
import com.ybear.ybnetworkutil.network.NetworkChangeManage;

import java.lang.ref.WeakReference;

/**
 * 网络触发器
 */
class HttpTrigger {
    /**
     * 触发器接口
     */
    public interface TriggerListener {
        void trigger();
    }

    private Application mApp;
    //网络状态管理器
    private NetworkChangeManage ncm;
    //触发器参数
    private String[] triggers = null;
    //当前网络类型  UNKNOWN = 未知网络，NONE = 无网络，WIFI = 无线网络，MOBILE = 移动网络
    private String currentNetworkType = null;
    private TriggerListener mTriggerListener = null;
    private OnNetworkChangeListener mChangeListener;
    //是否启动接收http请求成功的处理
    private boolean isStartResponse = false;

    private HttpTrigger() { }
    public static HttpTrigger get() { return HttpTrigger.HANDLER.I; }
    private static class HANDLER { private static final HttpTrigger I = new HttpTrigger();}

    public HttpTrigger init(Application app) {
        mApp = new WeakReference<>( app ).get();
        return this;
    }

    public void release() {
        //释放网络状态管理器
        if( ncm != null ) ncm.unregisterService();
        triggers = null;
        currentNetworkType = null;
        mTriggerListener = null;
        mChangeListener = null;
        isStartResponse = false;
    }

    /**
     * 启动触发器
     * 触发器允许多次调用，但触发器仅在停止运行时启动（多次调用，仅会执行一次）
     */
    public void start() {
        int networkCount = 0;
        String type = TriggerNetworkType.NONE;
        //未设置触发器，抛异常
        if( triggers == null || triggers.length == 0 ) {
            throw new NullPointerException("Not set any triggers.");
        }
        //根据触发器参数处理触发器
        for( String trigger : triggers ) {
            switch ( trigger ) {
                case ReCountTrigger.NETWORK_AVAILABLE:     //存在网络时
                    networkCount++;
                    type = TriggerNetworkType.AVAILABLE;
                    break;
                case ReCountTrigger.NETWORK_SWITCH:        //网络切换时
                    networkCount++;
                    type = TriggerNetworkType.SWITCH;
                    break;
                case ReCountTrigger.EXIST_RESPONSE:        //存在成功的Http请求时
                    triggerExistResponse();
                    break;
            }
        }
        //网络触发器
        triggerNetwork( networkCount >= 2 ? TriggerNetworkType.ALL : type );
    }

    /**
     * 网络状态触发处理
     * @param networkType   当前触发的类型
     */
    private void triggerNetwork(@TriggerNetworkType String networkType) {
        if( ncm != null && TriggerNetworkType.NONE.equals( networkType ) ) { return; }
        //网络状态改变管理器
        ncm = NetworkChangeManage.get().init( mApp );

        if( mChangeListener == null ) {
            mChangeListener = (isAvailable, type) -> {
                if( mTriggerListener == null ) return;
                switch ( networkType ) {
                    case TriggerNetworkType.SWITCH:    //切换网络
                        doNetworkSwitch( type );
                        break;
                    case TriggerNetworkType.AVAILABLE: //是否在线
                        doNetworkAvailable( isAvailable );
                        break;
                    case TriggerNetworkType.ALL:       //所有操作
                        if( !doNetworkAvailable( isAvailable ) ) doNetworkSwitch( type );
                        break;
                }
            };
            //注册网络状态回调
            ncm.registerNetworkChange( mChangeListener );
            //注册监听网络状态服务
            ncm.registerService();
        }
    }

    /**
     * 存在成功的http请求处理
     */
    private void triggerExistResponse() {
        isStartResponse = true;
    }

    /**
     * 设置触发监听器
     * @param mTriggerListener  监听器
     * @return                  {@link HttpTrigger}
     */
    public HttpTrigger setTriggerListener(TriggerListener mTriggerListener) {
        this.mTriggerListener = mTriggerListener;
        return this;
    }

    /**
     * 设置重置触发器参数
     * @param triggers      {@link ReCountTrigger#NETWORK_AVAILABLE}   网络可用时触发
     *                      {@link ReCountTrigger#NETWORK_SWITCH}      网络切换时触发
     *                      {@link ReCountTrigger#EXIST_RESPONSE}      存在发起请求并且成功响应时触发
     * @return              this
     */
    public HttpTrigger setReCountTrigger(@ReCountTrigger @NonNull String... triggers) {
        this.triggers = triggers;
        return this;
    }

    /**
     * 处理网络切换的操作
     * @param nowType       当前传入的类型
     * @return              处理结果
     */
    private boolean doNetworkSwitch(@TriggerNetworkType String nowType) {
        if( currentNetworkType != null && !currentNetworkType.equals( nowType ) ) {
            mTriggerListener.trigger();
            return true;
        }
        currentNetworkType = nowType;
        return false;
    }

    /**
     * 处理网络状态正常时的操作
     * @param isAvailable   是否在线
     * @return              处理结果
     */
    private boolean doNetworkAvailable(boolean isAvailable) {
        if( isAvailable ) mTriggerListener.trigger();
        return isAvailable;
    }

    /**
     * 处理存在成功请求的操作
     * 触发条件中如果存在 {@link TriggerNetworkType#EXIST_RESPONSE } 时，那么必须在Http请求成功后调用该接口，
     * 否则无法处理这个条件的触发器
     * @return             {@link HttpTrigger}
     */
    public HttpTrigger doExistResponse() {
        if( mTriggerListener != null && isStartResponse ) mTriggerListener.trigger();
        return this;
    }
}